import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
import _objectSpread from '@babel/runtime/helpers/esm/objectSpread2';
import _objectWithoutProperties from '@babel/runtime/helpers/esm/objectWithoutProperties';
import _slicedToArray from '@babel/runtime/helpers/esm/slicedToArray';
import { Button, Col } from 'antd';
import classnames from 'classnames';
import React, { Fragment, useCallback, useImperativeHandle, useMemo } from 'react';
import Form from '../../../Form';
import { ClsPrefix } from '../../../consts';
import { defaultLayout } from '../../consts';
import { SchemaFormProvider } from '../../contexts/SchemaFormContext';
import { getFields } from '../../register';
import './index.css';
var _excluded = [
    'form',
    'fields',
    'className',
    'onSubmit',
    'onCancel',
    'layout',
    'footer',
    'Fields',
    'FieldWrap',
  ],
  _excluded2 = ['fieldType'];
/**
 * 依据 schema 渲染的表单
 * @param form FormInstance，操作表单数据的实例
 * @param fields 表单项的 schema 表示
 * @param className 样式类
 * @param onSubmit 提交操作
 * @param onCancel 取消操作
 * @param layout 布局
 * @param Fields 表单项渲染器映射
 */
var InternalForm = function InternalForm(_ref, ref) {
  var _classnames;
  var formInstance = _ref.form,
    fields = _ref.fields,
    className = _ref.className,
    onSubmit = _ref.onSubmit,
    onCancel = _ref.onCancel,
    _ref$layout = _ref.layout,
    layout = _ref$layout === void 0 ? 'vertical' : _ref$layout,
    footer = _ref.footer,
    FieldsProp = _ref.Fields,
    FieldWrap = _ref.FieldWrap,
    rest = _objectWithoutProperties(_ref, _excluded);
  var _Form$useForm = Form.useForm(),
    _Form$useForm2 = _slicedToArray(_Form$useForm, 1),
    form = _Form$useForm2[0];
  /** 允许字段设置 onChange */
  var fieldsShouldBindChange = useMemo(
    function () {
      return fields.filter(function (field) {
        return !!field.onChange;
      });
    },
    [fields],
  );
  var formManager = useMemo(
    function () {
      var internalFormManager =
        formInstance !== null && formInstance !== void 0 ? formInstance : form;
      return _objectSpread(
        _objectSpread({}, internalFormManager),
        {},
        {
          setFields: function setFields(flds) {
            internalFormManager.setFields(flds);
            if (
              !('__powerBySzzjSchemaForm' in internalFormManager) ||
              !internalFormManager.__powerBySzzjSchemaForm
            ) {
              fieldsShouldBindChange.forEach(function (field) {
                var found = flds.find(function (fe) {
                  return fe.name === field.name;
                });
                if (found) field.onChange(found.value);
              });
            }
          },
          /**
           * 赋值联动
           * @param values
           */
          setFieldsValue: function setFieldsValue(values) {
            internalFormManager.setFieldsValue(values);
            if (
              !('__powerBySzzjSchemaForm' in internalFormManager) ||
              !internalFormManager.__powerBySzzjSchemaForm
            ) {
              fieldsShouldBindChange.forEach(function (field) {
                if (values[field.name] !== undefined) {
                  field.onChange(values[field.name]);
                }
              });
            }
          },
        },
      );
    },
    [form, fieldsShouldBindChange, formInstance],
  );
  useImperativeHandle(
    ref,
    function () {
      return formManager;
    },
    [formManager],
  );
  var FieldsMap = useMemo(
    function () {
      return FieldsProp ? _objectSpread(_objectSpread({}, getFields()), FieldsProp) : getFields();
    },
    [FieldsProp],
  );
  var formClassName = classnames(
    ((_classnames = {}),
    _defineProperty(_classnames, className, !!className),
    _defineProperty(_classnames, ''.concat(ClsPrefix, '-schema-form'), true),
    _classnames),
  );
  var labelCol = useMemo(
    function () {
      return rest.labelCol || defaultLayout.labelCol;
    },
    [rest],
  );
  var wrapperCol = useMemo(
    function () {
      return rest.wrapperCol || defaultLayout.wrapperCol;
    },
    [rest],
  );
  var btnColLayout = useMemo(
    function () {
      var _labelCol$xs,
        _wrapperCol$xs,
        _labelCol$sm,
        _wrapperCol$sm,
        _labelCol$xxl,
        _wrapperCol$xxl;
      return (labelCol === null || labelCol === void 0 ? void 0 : labelCol.span)
        ? {
            offset: labelCol.span,
            span: wrapperCol === null || wrapperCol === void 0 ? void 0 : wrapperCol.span,
          }
        : {
            xs: {
              offset:
                labelCol === null || labelCol === void 0
                  ? void 0
                  : (_labelCol$xs = labelCol.xs) === null || _labelCol$xs === void 0
                  ? void 0
                  : _labelCol$xs.span,
              span:
                wrapperCol === null || wrapperCol === void 0
                  ? void 0
                  : (_wrapperCol$xs = wrapperCol.xs) === null || _wrapperCol$xs === void 0
                  ? void 0
                  : _wrapperCol$xs.span,
            },
            sm: {
              offset:
                labelCol === null || labelCol === void 0
                  ? void 0
                  : (_labelCol$sm = labelCol.sm) === null || _labelCol$sm === void 0
                  ? void 0
                  : _labelCol$sm.span,
              span:
                wrapperCol === null || wrapperCol === void 0
                  ? void 0
                  : (_wrapperCol$sm = wrapperCol.sm) === null || _wrapperCol$sm === void 0
                  ? void 0
                  : _wrapperCol$sm.span,
            },
            xxl: {
              offset:
                labelCol === null || labelCol === void 0
                  ? void 0
                  : (_labelCol$xxl = labelCol.xxl) === null || _labelCol$xxl === void 0
                  ? void 0
                  : _labelCol$xxl.span,
              span:
                wrapperCol === null || wrapperCol === void 0
                  ? void 0
                  : (_wrapperCol$xxl = wrapperCol.xxl) === null || _wrapperCol$xxl === void 0
                  ? void 0
                  : _wrapperCol$xxl.span,
            },
          };
    },
    [labelCol, wrapperCol],
  );
  var handleSubmit = useCallback(
    function () {
      formManager.validateFields().then(function (vals) {
        onSubmit === null || onSubmit === void 0 ? void 0 : onSubmit(vals);
      });
    },
    [formManager, onSubmit],
  );
  var btns = useMemo(
    function () {
      if (footer === false || !!rest.detail) return null;
      return footer
        ? footer(formManager)
        : /*#__PURE__*/ React.createElement(
            Fragment,
            null,
            /*#__PURE__*/ React.createElement(
              Button,
              {
                type: 'primary',
                onClick: handleSubmit,
              },
              '\u63D0\u4EA4',
            ),
            /*#__PURE__*/ React.createElement(
              Button,
              {
                style: {
                  marginLeft: 10,
                },
                onClick: onCancel,
              },
              '\u53D6\u6D88',
            ),
          );
    },
    [footer, formManager, handleSubmit, onCancel],
  );
  return /*#__PURE__*/ React.createElement(
    SchemaFormProvider,
    {
      value: {
        form: formManager,
        Fields: FieldsMap,
        FieldWrap: FieldWrap,
      },
    },
    /*#__PURE__*/ React.createElement(
      Form,
      _objectSpread(
        _objectSpread(
          {
            scrollToFirstError: true,
            preserve: false,
          },
          rest,
        ),
        {},
        {
          className: formClassName,
          layout: layout,
          labelCol: layout === 'horizontal' ? labelCol : undefined,
          wrapperCol: layout === 'horizontal' ? wrapperCol : undefined,
          form: formManager,
        },
      ),
      fields.map(function (field) {
        var _field$fieldType = field.fieldType,
          fieldType = _field$fieldType === void 0 ? 'input' : _field$fieldType,
          fieldProps = _objectWithoutProperties(field, _excluded2);
        var FieldComp = FieldsMap[fieldType];
        var innerProps = {};
        if (['input', 'textarea', 'select', 'cascader', 'tree-select'].includes(fieldType)) {
          innerProps.allowClear =
            fieldProps.allowClear === undefined ? true : fieldProps.allowClear;
        }
        var fieldNode = /*#__PURE__*/ React.createElement(
          FieldComp,
          _objectSpread(
            _objectSpread(
              _objectSpread({}, innerProps),
              {},
              {
                required: true,
              },
              fieldProps,
            ),
            {},
            {
              key: fieldProps.key || fieldProps.name,
              form: formManager,
            },
          ),
        );
        return FieldWrap
          ? /*#__PURE__*/ React.createElement(
              FieldWrap,
              {
                key: fieldProps.key || fieldProps.name,
              },
              fieldNode,
            )
          : fieldNode;
      }),
      layout === 'horizontal'
        ? /*#__PURE__*/ React.createElement(Col, _objectSpread({}, btnColLayout), btns)
        : btns,
    ),
  );
};
var SchemaForm = /*#__PURE__*/ React.forwardRef(InternalForm);
export default SchemaForm;
